package cantools

import "gitee.com/CoolguyHolmes/socketcan-fd"

// xxOption 参数结构体
// 注意xxOption中存在但是newxxOption中没有初始化的, 都是创建时必须提供的选项
type canInterfaceOption struct {
	canIfsName    []fd.InterfaceCfg
	mirror        bool
	mirrorPath    string
	serialization Serialization
}

// 注意xxOption中存在但是newxxOption中没有初始化的, 都是创建时必须提供的选项
type repeaterOption struct {
	fdName string
	can    *Can
}

// newXxOption 默认参数生成
func newCanInterfaceOption(opts []canInterfaceOptions) *canInterfaceOption {
	o := &canInterfaceOption{
		canIfsName: []fd.InterfaceCfg{{
			IfName:   "can0",
			Channel:  0,
			Flag:     fd.CANChannel_FD,
			BitrateA: 500,
			BitrateD: 0,
		}, {
			IfName:   "can1",
			Channel:  1,
			Flag:     fd.CANChannel_FD,
			BitrateA: 500,
			BitrateD: 0,
		}, {
			IfName:   "can2",
			Channel:  2,
			Flag:     fd.CANChannel_FD,
			BitrateA: 500,
			BitrateD: 0,
		}, {
			IfName:   "can3",
			Channel:  3,
			Flag:     fd.CANChannel_FD,
			BitrateA: 500,
			BitrateD: 0,
		}, {
			IfName:   "can4",
			Channel:  4,
			Flag:     fd.CANChannel_FD,
			BitrateA: 500,
			BitrateD: 0,
		}},
		mirror:        false,
		mirrorPath:    "mirror.log",
		serialization: &defaultSerialization{},
	}

	for _, opt := range opts {
		opt.apply(o)
	}
	return o
}

// newXxOption 默认参数生成
func newRepeaterOption(opts []repeaterOptions) *repeaterOption {
	o := &repeaterOption{
		// 被注释的说明没有默认参数, 是调用是必须输入的参数
		//fdName:            "",
		//can:    nil,
	}

	for _, opt := range opts {
		opt.apply(o)
	}

	return o
}

/* 对外暴露的类型 */

type FdNameRepeaterOption string
type CanIfsNameCanInterfaceOption []fd.InterfaceCfg
type MirrorCanInterfaceOption bool
type MirrorPathCanInterfaceOption string
type CanRepeaterOption struct {
	*Can
}

// SerializationCanInterfaceOption 如果要传入的不是一个基础类型, 就用结构体封装起来
type SerializationCanInterfaceOption struct {
	Serialization
}

// 套壳
func (c CanRepeaterOption) apply(opt *repeaterOption) {
	opt.can = c.Can
}
func (s SerializationCanInterfaceOption) apply(opt *canInterfaceOption) {
	opt.serialization = s.Serialization
}
func (c FdNameRepeaterOption) apply(opt *repeaterOption) {
	opt.fdName = string(c)
}
func (c CanIfsNameCanInterfaceOption) apply(opt *canInterfaceOption) {
	opt.canIfsName = c
}
func (m MirrorCanInterfaceOption) apply(opt *canInterfaceOption) {
	opt.mirror = bool(m)
}
func (m MirrorPathCanInterfaceOption) apply(opt *canInterfaceOption) {
	opt.mirrorPath = string(m)
}

// xxOptions -> interface  非对外的interface首字母小写, 和上面的结构体命名很相似, s代表interface
type canInterfaceOptions interface {
	apply(*canInterfaceOption)
}
type repeaterOptions interface {
	apply(*repeaterOption)
}
